package com.miraclesea.module.rbac.service.impl;

import javax.annotation.Resource;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.miraclesea.module.rbac.dao.RoleDao;
import com.miraclesea.module.rbac.entity.Role;
import com.miraclesea.module.rbac.exception.RoleNameIsUsedException;
import com.miraclesea.module.rbac.service.RoleService;

@Service
@Transactional(readOnly = true)
public final class RoleServiceImpl implements RoleService {
	
	@Resource
	private RoleDao roleDao;
	
	@Override
	@Transactional(readOnly = false)
	public void create(final Role role) {
		validateRole(role);
		roleDao.save(role);
	}
	
	@Override
	@Transactional(readOnly = false)
	public void update(final Role role) {
		validateRole(role);
		roleDao.updateNotNull(role);
	}
	
	@Override
	@Transactional(readOnly = false)
	public void delete(final String id) {
		roleDao.delete(id);
	}
	
	@Override
	@Transactional(readOnly = false)
	public Role load(final String id) {
		return roleDao.findOne(id);
	}
	
	@Override
	public Page<Role> findAll(final Pageable pageable) {
		return roleDao.findAll(pageable);
	}
	
	@Override
	public boolean isUsedRoleName(final Role role) {
		try {
			validateRole(role);
		} catch (final RoleNameIsUsedException ex) {
			return true;
		}
		return false;
	}
	
	private void validateRole(final Role role) throws RoleNameIsUsedException {
		Role roleFromDb;
		if (role.isNew()) {
			roleFromDb = roleDao.findByName(role.getName());
		} else {
			roleFromDb = roleDao.findByName(role.getName(), role.getId());
		}
		if (null != roleFromDb) {
			throw new RoleNameIsUsedException();
		}
	}
}
